package com.archeanx.libx.http;


import androidx.annotation.NonNull;
import androidx.collection.ArrayMap;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;

/**
 * 获取一个retrofit实例
 *
 * @author admin
 */
public class XHttpHelper {

    private XHttpHelper() {
    }

    public static XHttpHelper getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static final class SingletonHolder {
        private static final XHttpHelper INSTANCE = new XHttpHelper();
    }

    /**
     * 是否打印头部日志
     */
    private boolean isShowHeadLogging = false;
    /**
     * 是否打印身体日志
     */
    private boolean isShowBodyLogging = false;

    public boolean isShowHeadLogging() {
        return isShowHeadLogging;
    }

    public boolean isShowBodyLogging() {
        return isShowBodyLogging;
    }

    /**
     * 是否启用 log
     *
     * @param isShowHeadLog 显示headlog
     * @param isShowBodyLog 显示bodylog
     */
    public static void enableLogging(boolean isShowHeadLog, boolean isShowBodyLog) {
        getInstance().isShowBodyLogging = isShowHeadLog;
        getInstance().isShowHeadLogging = isShowBodyLog;
    }


    /**
     * 存储 retrofit 的 接口实例
     * <p>
     * key-   包名.文件名
     * <p>
     * value- 接口类 实例
     */
    private ArrayMap<String, Object> mInterfaceMap = new ArrayMap<>();

    /**
     * 存储  Retrofit 实例
     * <p>
     * key-  baseUrl
     * <p>
     * value- Retrofit 实例
     */
    private ArrayMap<String, Retrofit> mRetrofitMap = new ArrayMap<>();

    /**
     * 绑定 retrofit 接口实例 Name 和 BaseUrl ;
     * 多个 接口实例 Name 可以对应一个 BaseUrl
     * key 接口实例 Name
     * value BaseUrl
     */
    private ArrayMap<String, String> mInterfaceNameToBaseUrl = new ArrayMap<>();


    /**
     * 监听
     */
    private XOnHttpRequestInitListener mXOnHttpRequestInitListener;
    /**
     * 全局可用client
     */
    private OkHttpClient mOkHttpClient;

    /**
     * 初始化默认使用
     */
    public static void initHttp() {
        initHttp(new XOnHttpRequestInitListener() {
        });
    }

    /**
     * 初始化
     *
     * @param listener 初始化监听
     */
    public static void initHttp(XOnHttpRequestInitListener listener) {
        if (listener != null) {
            getInstance().mXOnHttpRequestInitListener = listener;
        }
    }


    /**
     * 获取okhttp实例
     *
     * @return 获取okhttp实例
     */
    public OkHttpClient getOkHttpClient() {
        if (getInstance().mXOnHttpRequestInitListener == null) {
            throw new RuntimeException("请初始化请求框架 XHttpHelper.initHttp()");
        }
        if (mOkHttpClient == null) {
            mOkHttpClient = getInstance().mXOnHttpRequestInitListener.initOkhttp();
        }
        return mOkHttpClient;
    }

    /**
     * 接口类 绑定  baseUrl
     *
     * @param baseUrl        当前请求的BaseUrl
     * @param interfaceClass 当前请求的 接口类
     *                       todo 当一个BaseUrl 只有几个 接口的时候，不建议 使用此方法，此方法会导致 Retrofit 实例 增加，并且不会被销毁
     *                       todo 每个 接口类 应当使用此方法
     */
    public static synchronized void onBindingBaseUrl(String baseUrl, Class interfaceClass) {
        if (getInstance().mXOnHttpRequestInitListener == null) {
            throw new RuntimeException("请初始化请求框架 XHttpHelper.initHttp()");
        }
        // 新的 baseUrl 生成新的 retrofit 实例
        if (getInstance().mRetrofitMap.get(baseUrl) == null) {
            getInstance().mRetrofitMap.put(baseUrl, getInstance().mXOnHttpRequestInitListener.initRetrofit(baseUrl));
        }
        if (getInstance().mInterfaceNameToBaseUrl.get(interfaceClass.getName()) == null) {
            getInstance().mInterfaceNameToBaseUrl.put(interfaceClass.getName(), baseUrl);
        }
        if (getInstance().mRetrofitMap.size() > 10) {
            throw new RuntimeException("BaseHttpRequest Error: Retrofit 实例 不允许超过10个 ！");
        }
    }

    /**
     * 根据传入的 interface 自动生成 各个接口类的实例，且不会重复生成
     */
    public static synchronized <T> T getInterfaceObject(@NonNull Class<T> interfaceClass) {
        //当 interface 没有实例
        if (getInstance().mInterfaceMap.get(interfaceClass.getName()) == null) {
            // 使用 interface Name 获取 baseUrl
            String baseUrl = getInstance().mInterfaceNameToBaseUrl.get(interfaceClass.getName());
            if (baseUrl == null) {
                throw new RuntimeException("BaseHttpRequest Error: 接口类未初始化，请使用 onBindingBaseUrl 绑定 BaseUrl");
            }
            // 使用 baseURL 获取 Retrofit 实例
            Retrofit retrofit = getInstance().mRetrofitMap.get(baseUrl);
            if (retrofit == null) {
                throw new RuntimeException("BaseHttpRequest Error: Retrofit 未实例化，请使用 onBindingBaseUrl 初始化接口类！");
            }
            getInstance().mInterfaceMap.put(interfaceClass.getName(), retrofit.create(interfaceClass));
        }

        return (T) getInstance().mInterfaceMap.get(interfaceClass.getName());
    }

    /**
     * 清理请求
     * todo 最好的方式，是替换，而不是清理
     */
    public void clearHttpRequest() {
        getInstance().mInterfaceNameToBaseUrl.clear();
        getInstance().mInterfaceMap.clear();
        getInstance().mRetrofitMap.clear();
    }

    /**
     * 获取当前所有的BaseUrl
     */
    public ArrayMap getBaseUrlsString() {
        return getInstance().mRetrofitMap;
    }

    /**
     * 获取当前所有的 接口类
     */
    public ArrayMap getInterfacesString() {
        return getInstance().mInterfaceMap;
    }

}
